﻿@using AntDesign.JsInterop
@using AntDesign.Docs.Services
@using System.Reflection;
@using System.Globalization
@implements IDisposable
@inherits ComponentBase

<div class="code-box" id="@DemoId">
    <section class="code-box-demo">
        @if (_rendered)
        {
            if (Demo.Iframe > 0)
            {
                <MockBrowser Height="@Demo.Iframe.Value" WithUrl="@(Demo.Link??$"/mock?demoId={DemoId}&type={Demo.Type}")" />
            }
            else
            {
                @if (_demoType != null)
                {
                     <ErrorBoundary @ref="_errorBoundary">
                        <ChildContent>
                              <DynamicComponent Type="_demoType" />
                        </ChildContent>
                        <ErrorContent Context="ex">
                            <Alert Type="AlertType.Error"
                                   Message="@ex.Message"
                                   Description="@ex.StackTrace">
                            </Alert>
                        </ErrorContent>
                    </ErrorBoundary>
                }
            }
        }
        else
        {
             <Skeleton ParagraphRows="3" Active></Skeleton>
        }
    </section>
    <section class="code-box-meta markdown">
        <div class="code-box-title" @onclick="@AnchorClick">
            <a @onclick="AnchorClick">@Demo.Title</a>
            <Tooltip Title="@Localizer["app.content.edit-demo"]">
                <Unbound>
                    <a @ref="context.Current" class="edit-button" href="@EditUrl" target="_blank" rel="noopener noreferrer">
                        <Icon Type="@IconType.Outline.Edit" />
                    </a>
                </Unbound>
            </Tooltip>
        </div>
        <div class="code-box-description">
            @((MarkupString)Demo.Description)
        </div>
        <div class="code-box-actions">
            <Tooltip Title="@Localizer[_copied?"app.demo.copied":"app.demo.copy"]" OnVisibleChange="() => _copied = false">
                <Unbound>
                    <Icon RefBack="context" Type="@(_copied ? IconType.Outline.Check : IconType.Outline.Snippets)" Class="code-box-code-copy code-box-code-action" OnClick="Copy" />
                </Unbound>
            </Tooltip>
            <Tooltip Title="@(_innerExpand?Localizer["app.demo.code.hide"] : Localizer["app.demo.code.show"])">
                <Unbound>
                    <span @ref="context.Current" class="code-expand-icon code-box-code-action" @onclick="_ => _innerExpand = !_innerExpand">
                        <img alt="expand code" src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg" class="@(_innerExpand ? "code-expand-icon-hide" : "code-expand-icon-show")">
                        <img alt="expand code" src="https://gw.alipayobjects.com/zos/rmsportal/OpROPHYqWmrMDBFMZtKF.svg" class="@(!_innerExpand ? "code-expand-icon-hide" : "code-expand-icon-show")">
                    </span>
                </Unbound>
            </Tooltip>
            @_debugIcon
        </div>
    </section>
    <section class="highlight-wrapper @(_innerExpand?"highlight-wrapper-expand":"")">
      @*   <div class="highlight">
            <HighlightedCode Code="@Demo.Code" CanLoad="_innerExpand" Language="html"></HighlightedCode>
        </div> *@
        @if (_innerExpand || _codeViewRendered)
        {
            _codeViewRendered = true;
            <CodeView @bind-Value="@Demo.Code" Compiled="OnCompiled" />
        }
    </section>
    <style>
        @Demo.Style
    </style>
</div>

@inject InteropService InteropService
@inject DemoService demoService;
@inject ILocalizationService lang;
@inject IStringLocalizer Localizer;

@code {

    [Parameter]
    public string ComponentName { get; set; }

    [Parameter]
    public DemoItem Demo { get; set; }

    [Parameter]
    public bool CodeExpand
    {
        get => _codeExpand;
        set
        {
            if (_codeExpand != value)
            {
                _codeExpand = value;
                _innerExpand = value;
            }
        }
    }

    private Type _demoType;

    RenderFragment _debugIcon;

    private bool _copied;
    private bool _rendered;
    private bool _codeViewRendered;
    private ErrorBoundary _errorBoundary;
    private bool _innerExpand;
    private bool _codeExpand;

    protected string DemoId => $"components-{ComponentName.ToLower()}-demo-{Demo.Name}";

    private string EditUrl => $"https://github.com/ant-design-blazor/ant-design-blazor/edit/master/site/AntDesign.Docs/{Demo.Type.Replace(".", "/")}.razor";

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        lang.LanguageChanged += OnLangeChanged;
#if DEBUG
        _debugIcon =
    @<a href="@(Demo.Link??$"mock?type={Demo.Type}")" class="code-box-code-action" target="_blank">
            <Icon Type="@IconType.Outline.Bug" />
    </a>
    ;
#endif
    }

    async Task Copy()
    {
        await InteropService.Copy(Demo.Code);
        _copied = true;
    }

    async Task AnchorClick()
    {
        await InteropService.JsInvokeAsync("window.eval", $"window.location.hash='{DemoId}'");
    }

    void IDisposable.Dispose()
    {
        lang.LanguageChanged -= OnLangeChanged;
    } 

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _rendered = true;
            StateHasChanged();
            return;
        }

        if (_rendered && _demoType == null)
        {
            _demoType = Type.GetType($"{Assembly.GetExecutingAssembly().GetName().Name}.{Demo.Type}");
            StateHasChanged();
        }
    }

    void OnCompiled(Type type)
    {
        _demoType = type;
        _errorBoundary.Recover();
        StateHasChanged();
    }

    private void OnLangeChanged(object sender, CultureInfo e)
    {
        _demoType = null;
        StateHasChanged();
    }
}
